{
 "cells": [
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "6cce5e50",
   "metadata": {},
   "outputs": [],
   "source": [
    "from qiskit import QuantumCircuit, qasm3\n",
    "from quantum_chip import QuantumChip\n",
    "from hardware import HardwareParams\n",
    "from qrmove_compiler import QRMoveCompiler\n",
    "from utils import get_quantum_circuit\n",
    "import math\n",
    "import signal"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "c0185d02",
   "metadata": {},
   "outputs": [],
   "source": [
    "# Default Settings\n",
    "# quantum_alg: bv\n",
    "# MRP_CP_ratio: 10\n",
    "# extra_qubit_ratio: 15%\n",
    "# qubit_num: 30\n",
    "\n",
    "\n",
    "class TimeoutError(Exception):\n",
    "    pass\n",
    "\n",
    "\n",
    "def timeout_handler(signum, frame):\n",
    "    raise TimeoutError(\"Function call timed out\")\n",
    "\n",
    "\n",
    "def experiment(quantum_alg, qubit_num, extra_qubit_num, MRP_CP_ratio):\n",
    "    \"\"\"\n",
    "    quantum_alg: 量子算法\n",
    "    qubit_num: 量子比特数量\n",
    "    extra_qubit_ratio: 额外比特比例\n",
    "    MRP_CP_ratio: MRP/CP 比例\n",
    "    \"\"\"\n",
    "    # 设置信号处理器和超时时间（5分钟）\n",
    "    signal.signal(signal.SIGALRM, timeout_handler)\n",
    "    signal.alarm(5 * 60)\n",
    "\n",
    "    try:\n",
    "        quantum_circuit: QuantumCircuit = get_quantum_circuit(quantum_alg, qubit_num)\n",
    "        quantum_chip = QuantumChip(\"square\", 50)\n",
    "        hardware_param = HardwareParams(\n",
    "            time_1q=300.0,  # 单比特门时间\n",
    "            time_2q=300.0,  # 双比特门时间\n",
    "            time_meas=300 * MRP_CP_ratio,  # 测量时间\n",
    "            time_reset=0,  # 重置时间\n",
    "        )\n",
    "        qmc = QRMoveCompiler(\n",
    "            quantum_circuit,\n",
    "            quantum_chip,\n",
    "            hardware_param,\n",
    "            math.ceil(extra_qubit_num),\n",
    "        )\n",
    "        (\n",
    "            start_depth,\n",
    "            start_width,\n",
    "            qr_map_depth,\n",
    "            qr_map_width,\n",
    "            qr_move_depth,\n",
    "            qr_move_width,\n",
    "        ) = qmc.compile_program()\n",
    "\n",
    "        # 取消警报\n",
    "        signal.alarm(0)\n",
    "        return (\n",
    "            start_depth,\n",
    "            start_width,\n",
    "            qr_map_depth,\n",
    "            qr_map_width,\n",
    "            qr_move_depth,\n",
    "            qr_move_width,\n",
    "        )\n",
    "\n",
    "    except (TimeoutError, Exception) as e:\n",
    "        # 取消警报以防万一\n",
    "        signal.alarm(0)\n",
    "        print(f\"Experiment failed with error: {e}\")\n",
    "        return 0, 0, 0, 0, 0, 0"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "08b9b989",
   "metadata": {},
   "outputs": [],
   "source": [
    "def experiment_var_extra_ratio_alg():\n",
    "    from concurrent.futures import ThreadPoolExecutor, as_completed\n",
    "    from functools import partial\n",
    "    \n",
    "    # 存储每个参数组合的任务结果\n",
    "    all_tasks = []\n",
    "    \n",
    "    # 创建所有参数组合\n",
    "    for alg in [\"bv\", \"vqa\", \"qaoa\", \"qft\", \"mul\", \"rd\", \"xor\"]:\n",
    "        for extra_ratio in [0.1, 0.2, 0.3]:\n",
    "            qubit_num = 30\n",
    "            all_tasks.append((alg, extra_ratio, qubit_num))\n",
    "    \n",
    "    # 为每个参数组合执行50次实验\n",
    "    def run_experiments_for_params(alg, extra_ratio, qubit_num):\n",
    "        results = []\n",
    "        for _ in range(50):\n",
    "            (\n",
    "                start_depth,\n",
    "                start_width,\n",
    "                qr_map_depth,\n",
    "                qr_map_width,\n",
    "                qr_move_depth,\n",
    "                qr_move_width,\n",
    "            ) = experiment(alg, qubit_num, extra_ratio * qubit_num, 10)\n",
    "            \n",
    "            # 如果实验成功（不是全零结果），则添加到结果列表中\n",
    "            if not (\n",
    "                start_depth == 0\n",
    "                and start_width == 0\n",
    "                and qr_map_depth == 0\n",
    "                and qr_map_width == 0\n",
    "                and qr_move_depth == 0\n",
    "                and qr_move_width == 0\n",
    "            ):\n",
    "                results.append(\n",
    "                    (\n",
    "                        start_depth,\n",
    "                        start_width,\n",
    "                        qr_map_depth,\n",
    "                        qr_map_width,\n",
    "                        qr_move_depth,\n",
    "                        qr_move_width,\n",
    "                    )\n",
    "                )\n",
    "        return alg, extra_ratio, qubit_num, results\n",
    "    \n",
    "    # 使用线程池并发执行所有实验\n",
    "    results_dict = {}\n",
    "    with ThreadPoolExecutor(max_workers=96) as executor:\n",
    "        # 提交所有任务\n",
    "        future_to_params = {\n",
    "            executor.submit(run_experiments_for_params, alg, extra_ratio, qubit_num): (alg, extra_ratio, qubit_num)\n",
    "            for alg, extra_ratio, qubit_num in all_tasks\n",
    "        }\n",
    "        \n",
    "        # 收集结果\n",
    "        for future in as_completed(future_to_params):\n",
    "            alg, extra_ratio, qubit_num, valid_results = future.result()\n",
    "            results_dict[(alg, extra_ratio)] = valid_results\n",
    "    \n",
    "    # 处理和打印结果\n",
    "    for alg in [\"bv\", \"vqa\", \"qaoa\", \"qft\", \"mul\", \"rd\", \"xor\"]:\n",
    "        for extra_ratio in [0.1, 0.2, 0.3]:\n",
    "            qubit_num = 30\n",
    "            valid_results = results_dict.get((alg, extra_ratio), [])\n",
    "            \n",
    "            print(\n",
    "                f\"-- 参数: {alg} 算法, 额外比特比例 {extra_ratio}, 量子比特数量 {qubit_num} --\"\n",
    "            )\n",
    "            \n",
    "            # 计算平均值\n",
    "            if valid_results:\n",
    "                avg_start_depth = sum(r[0] for r in valid_results) / len(valid_results)\n",
    "                avg_start_width = sum(r[1] for r in valid_results) / len(valid_results)\n",
    "                avg_qr_map_depth = sum(r[2] for r in valid_results) / len(valid_results)\n",
    "                avg_qr_map_width = sum(r[3] for r in valid_results) / len(valid_results)\n",
    "                avg_qr_move_depth = sum(r[4] for r in valid_results) / len(\n",
    "                    valid_results\n",
    "                )\n",
    "                avg_qr_move_width = sum(r[5] for r in valid_results) / len(\n",
    "                    valid_results\n",
    "                )\n",
    "\n",
    "                print(\n",
    "                    f\"平均值: {avg_start_depth}, {avg_start_width}, {avg_qr_map_depth}, {avg_qr_map_width}, {avg_qr_move_depth}, {avg_qr_move_width}\"\n",
    "                )\n",
    "                print(f\"有效实验次数: {len(valid_results)}\")\n",
    "            else:\n",
    "                print(\"所有实验都失败了，无法计算平均值\")\n",
    "\n",
    "experiment_var_extra_ratio_alg()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "0201412c",
   "metadata": {},
   "outputs": [],
   "source": [
    "def experiment_var_qubit_num():\n",
    "    from concurrent.futures import ThreadPoolExecutor, as_completed\n",
    "    \n",
    "    # 存储每个参数组合的任务\n",
    "    all_tasks = []\n",
    "    \n",
    "    # 创建所有参数组合\n",
    "    qubit_nums = [10, 20, 30, 40, 50]\n",
    "    algorithms = [\"bv\", \"vqa\", \"qaoa\", \"qft\", \"mul\", \"rd\", \"xor\"]\n",
    "    \n",
    "    for qubit_num in qubit_nums:\n",
    "        for alg in algorithms:\n",
    "            MRP_CP_ratio = 10\n",
    "            extra_qubit_ratio = 0.15\n",
    "            all_tasks.append((alg, qubit_num, MRP_CP_ratio, extra_qubit_ratio))\n",
    "    \n",
    "    # 为每个参数组合执行50次实验\n",
    "    def run_experiments_for_params(alg, qubit_num, MRP_CP_ratio, extra_qubit_ratio):\n",
    "        results = []\n",
    "        for _ in range(50):\n",
    "            (\n",
    "                start_depth,\n",
    "                start_width,\n",
    "                qr_map_depth,\n",
    "                qr_map_width,\n",
    "                qr_move_depth,\n",
    "                qr_move_width,\n",
    "            ) = experiment(alg, qubit_num, extra_qubit_ratio * qubit_num, MRP_CP_ratio)\n",
    "            \n",
    "            # 如果实验成功（不是全零结果），则添加到结果列表中\n",
    "            if not (\n",
    "                start_depth == 0\n",
    "                and start_width == 0\n",
    "                and qr_map_depth == 0\n",
    "                and qr_map_width == 0\n",
    "                and qr_move_depth == 0\n",
    "                and qr_move_width == 0\n",
    "            ):\n",
    "                results.append(\n",
    "                    (\n",
    "                        start_depth,\n",
    "                        start_width,\n",
    "                        qr_map_depth,\n",
    "                        qr_map_width,\n",
    "                        qr_move_depth,\n",
    "                        qr_move_width,\n",
    "                    )\n",
    "                )\n",
    "        return alg, qubit_num, MRP_CP_ratio, extra_qubit_ratio, results\n",
    "    \n",
    "    # 使用线程池并发执行所有实验\n",
    "    results_dict = {}\n",
    "    with ThreadPoolExecutor(max_workers=96) as executor:\n",
    "        # 提交所有任务\n",
    "        future_to_params = {\n",
    "            executor.submit(run_experiments_for_params, alg, qubit_num, MRP_CP_ratio, extra_qubit_ratio): \n",
    "            (alg, qubit_num, MRP_CP_ratio, extra_qubit_ratio)\n",
    "            for alg, qubit_num, MRP_CP_ratio, extra_qubit_ratio in all_tasks\n",
    "        }\n",
    "        \n",
    "        # 收集结果\n",
    "        for future in as_completed(future_to_params):\n",
    "            alg, qubit_num, MRP_CP_ratio, extra_qubit_ratio, valid_results = future.result()\n",
    "            results_dict[(alg, qubit_num)] = valid_results\n",
    "    \n",
    "    # 处理和打印结果\n",
    "    for qubit_num in qubit_nums:\n",
    "        for alg in algorithms:\n",
    "            MRP_CP_ratio = 10\n",
    "            extra_qubit_ratio = 0.15\n",
    "            valid_results = results_dict.get((alg, qubit_num), [])\n",
    "            \n",
    "            print(\n",
    "                f\"-- 参数: {alg} 算法, 额外比特比例 {extra_qubit_ratio}, 量子比特数量 {qubit_num} --\"\n",
    "            )\n",
    "            \n",
    "            # 计算平均值\n",
    "            if valid_results:\n",
    "                avg_start_depth = sum(r[0] for r in valid_results) / len(valid_results)\n",
    "                avg_start_width = sum(r[1] for r in valid_results) / len(valid_results)\n",
    "                avg_qr_map_depth = sum(r[2] for r in valid_results) / len(valid_results)\n",
    "                avg_qr_map_width = sum(r[3] for r in valid_results) / len(valid_results)\n",
    "                avg_qr_move_depth = sum(r[4] for r in valid_results) / len(valid_results)\n",
    "                avg_qr_move_width = sum(r[5] for r in valid_results) / len(valid_results)\n",
    "\n",
    "                print(\n",
    "                    f\"平均值: {avg_start_depth}, {avg_start_width}, {avg_qr_map_depth}, {avg_qr_map_width}, {avg_qr_move_depth}, {avg_qr_move_width}\"\n",
    "                )\n",
    "                print(f\"有效实验次数: {len(valid_results)}\")\n",
    "            else:\n",
    "                print(\"所有实验都失败了，无法计算平均值\")"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "0d9fccf4",
   "metadata": {},
   "outputs": [],
   "source": [
    "def experiment_var_mrp_ratio():\n",
    "    from concurrent.futures import ThreadPoolExecutor, as_completed\n",
    "\n",
    "    # 存储每个参数组合的任务\n",
    "    all_tasks = []\n",
    "\n",
    "    # 创建所有参数组合\n",
    "    mrp_ratios = [5, 10, 15, 20, 25]\n",
    "    for MRP_CP_ratio in mrp_ratios:\n",
    "        all_tasks.append((\"bv\", 50, MRP_CP_ratio, 0.15 * 50))\n",
    "\n",
    "    # 为每个参数组合执行50次实验\n",
    "    def run_experiments_for_params(alg, qubit_num, MRP_CP_ratio, extra_qubit_num):\n",
    "        results = []\n",
    "        for _ in range(50):\n",
    "            (\n",
    "                start_depth,\n",
    "                start_width,\n",
    "                qr_map_depth,\n",
    "                qr_map_width,\n",
    "                qr_move_depth,\n",
    "                qr_move_width,\n",
    "            ) = experiment(alg, qubit_num, extra_qubit_num, MRP_CP_ratio)\n",
    "\n",
    "            # 如果实验成功（不是全零结果），则添加到结果列表中\n",
    "            if not (\n",
    "                start_depth == 0\n",
    "                and start_width == 0\n",
    "                and qr_map_depth == 0\n",
    "                and qr_map_width == 0\n",
    "                and qr_move_depth == 0\n",
    "                and qr_move_width == 0\n",
    "            ):\n",
    "                results.append(\n",
    "                    (\n",
    "                        start_depth,\n",
    "                        start_width,\n",
    "                        qr_map_depth,\n",
    "                        qr_map_width,\n",
    "                        qr_move_depth,\n",
    "                        qr_move_width,\n",
    "                    )\n",
    "                )\n",
    "        return alg, qubit_num, MRP_CP_ratio, extra_qubit_num, results\n",
    "\n",
    "    # 使用线程池并发执行所有实验\n",
    "    results_dict = {}\n",
    "    with ThreadPoolExecutor(max_workers=96) as executor:\n",
    "        # 提交所有任务\n",
    "        future_to_params = {\n",
    "            executor.submit(\n",
    "                run_experiments_for_params,\n",
    "                alg,\n",
    "                qubit_num,\n",
    "                MRP_CP_ratio,\n",
    "                extra_qubit_num,\n",
    "            ): (alg, qubit_num, MRP_CP_ratio, extra_qubit_num)\n",
    "            for alg, qubit_num, MRP_CP_ratio, extra_qubit_num in all_tasks\n",
    "        }\n",
    "\n",
    "        # 收集结果\n",
    "        for future in as_completed(future_to_params):\n",
    "            alg, qubit_num, MRP_CP_ratio, extra_qubit_num, valid_results = (\n",
    "                future.result()\n",
    "            )\n",
    "            results_dict[MRP_CP_ratio] = valid_results\n",
    "\n",
    "    # 处理和打印结果\n",
    "    for MRP_CP_ratio in mrp_ratios:\n",
    "        valid_results = results_dict.get(MRP_CP_ratio, [])\n",
    "\n",
    "        print(f\"-- 参数: bv 算法, 量子比特数量 50, MRP/CP 比例 {MRP_CP_ratio} --\")\n",
    "\n",
    "        # 计算平均值\n",
    "        if valid_results:\n",
    "            avg_start_depth = sum(r[0] for r in valid_results) / len(valid_results)\n",
    "            avg_start_width = sum(r[1] for r in valid_results) / len(valid_results)\n",
    "            avg_qr_map_depth = sum(r[2] for r in valid_results) / len(valid_results)\n",
    "            avg_qr_map_width = sum(r[3] for r in valid_results) / len(valid_results)\n",
    "            avg_qr_move_depth = sum(r[4] for r in valid_results) / len(valid_results)\n",
    "            avg_qr_move_width = sum(r[5] for r in valid_results) / len(valid_results)\n",
    "\n",
    "            print(\n",
    "                f\"平均值: {avg_start_depth}, {avg_start_width}, {avg_qr_map_depth}, {avg_qr_map_width}, {avg_qr_move_depth}, {avg_qr_move_width}\"\n",
    "            )\n",
    "            print(f\"有效实验次数: {len(valid_results)}\")\n",
    "        else:\n",
    "            print(\"所有实验都失败了，无法计算平均值\")\n",
    "\n",
    "\n",
    "experiment_var_mrp_ratio()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "b5270d84",
   "metadata": {},
   "outputs": [],
   "source": [
    "def experiment_var_width_depth():\n",
    "    from concurrent.futures import ThreadPoolExecutor, as_completed\n",
    "    \n",
    "    # 存储每个参数组合的任务\n",
    "    all_tasks = []\n",
    "    \n",
    "    # 创建所有参数组合\n",
    "    qubit_num = 30\n",
    "    MRP_CP_ratio = 10\n",
    "    alg = \"bv\"\n",
    "    for extra_qubit in range(30):\n",
    "        all_tasks.append((alg, qubit_num, extra_qubit, MRP_CP_ratio))\n",
    "    \n",
    "    # 为每个参数组合执行50次实验\n",
    "    def run_experiments_for_params(alg, qubit_num, extra_qubit, MRP_CP_ratio):\n",
    "        results = []\n",
    "        for _ in range(50):\n",
    "            (\n",
    "                start_depth,\n",
    "                start_width,\n",
    "                qr_map_depth,\n",
    "                qr_map_width,\n",
    "                qr_move_depth,\n",
    "                qr_move_width,\n",
    "            ) = experiment(alg, qubit_num, extra_qubit, MRP_CP_ratio)\n",
    "            \n",
    "            # 如果实验成功（不是全零结果），则添加到结果列表中\n",
    "            if not (\n",
    "                start_depth == 0\n",
    "                and start_width == 0\n",
    "                and qr_map_depth == 0\n",
    "                and qr_map_width == 0\n",
    "                and qr_move_depth == 0\n",
    "                and qr_move_width == 0\n",
    "            ):\n",
    "                results.append(\n",
    "                    (\n",
    "                        start_depth,\n",
    "                        start_width,\n",
    "                        qr_map_depth,\n",
    "                        qr_map_width,\n",
    "                        qr_move_depth,\n",
    "                        qr_move_width,\n",
    "                    )\n",
    "                )\n",
    "        return alg, qubit_num, extra_qubit, MRP_CP_ratio, results\n",
    "    \n",
    "    # 使用线程池并发执行所有实验\n",
    "    results_dict = {}\n",
    "    with ThreadPoolExecutor(max_workers=96) as executor:\n",
    "        # 提交所有任务\n",
    "        future_to_params = {\n",
    "            executor.submit(run_experiments_for_params, alg, qubit_num, extra_qubit, MRP_CP_ratio): \n",
    "            (alg, qubit_num, extra_qubit, MRP_CP_ratio)\n",
    "            for alg, qubit_num, extra_qubit, MRP_CP_ratio in all_tasks\n",
    "        }\n",
    "        \n",
    "        # 收集结果\n",
    "        for future in as_completed(future_to_params):\n",
    "            alg, qubit_num, extra_qubit, MRP_CP_ratio, valid_results = future.result()\n",
    "            results_dict[extra_qubit] = valid_results\n",
    "    \n",
    "    # 处理和打印结果\n",
    "    for extra_qubit in range(30):\n",
    "        valid_results = results_dict.get(extra_qubit, [])\n",
    "        \n",
    "        print(\n",
    "            f\"-- 参数: {alg} 算法, 量子比特数量 {qubit_num}, 额外量子比特数 {extra_qubit}, MRP/CP 比例 {MRP_CP_ratio} --\"\n",
    "        )\n",
    "        \n",
    "        # 计算平均值\n",
    "        if valid_results:\n",
    "            avg_start_depth = sum(r[0] for r in valid_results) / len(valid_results)\n",
    "            avg_start_width = sum(r[1] for r in valid_results) / len(valid_results)\n",
    "            avg_qr_map_depth = sum(r[2] for r in valid_results) / len(valid_results)\n",
    "            avg_qr_map_width = sum(r[3] for r in valid_results) / len(valid_results)\n",
    "            avg_qr_move_depth = sum(r[4] for r in valid_results) / len(valid_results)\n",
    "            avg_qr_move_width = sum(r[5] for r in valid_results) / len(valid_results)\n",
    "\n",
    "            print(\n",
    "                f\"平均值: {avg_start_depth}, {avg_start_width}, {avg_qr_map_depth}, {avg_qr_map_width}, {avg_qr_move_depth}, {avg_qr_move_width}\"\n",
    "            )\n",
    "            print(f\"有效实验次数: {len(valid_results)}\")\n",
    "        else:\n",
    "            print(\"所有实验都失败了，无法计算平均值\")\n",
    "\n",
    "experiment_var_width_depth()"
   ]
  }
 ],
 "metadata": {
  "kernelspec": {
   "display_name": "Python 3",
   "language": "python",
   "name": "python3"
  },
  "language_info": {
   "codemirror_mode": {
    "name": "ipython",
    "version": 3
   },
   "file_extension": ".py",
   "mimetype": "text/x-python",
   "name": "python",
   "nbconvert_exporter": "python",
   "pygments_lexer": "ipython3",
   "version": "3.10.18"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 5
}
